#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <gmp.h>
#include "montecarlo.h"

#define N_OUT 10
#define N_THREADS	4
#define RANDS_BY_OUT 2000000
#define IT_FILENAME "resultados/pth"
#define F_PREC 33219314

pthread_t callThd[N_THREADS];
pthread_mutex_t mutexcount;


RANDCORE rc[N_THREADS];
COUNTERS c[N_THREADS], total;


void *mc_rand_th(void *arg){
	long int nthr = (long int) arg;
	int flag;

	rc[nthr].n = RANDS_BY_OUT;
	while(rc[nthr].n--){
			flag = get_rand_point(rc+nthr);
			add_count(c+nthr, flag);
	}	

	pthread_mutex_lock (&mutexcount);
		mpf_add(total.in , total.in, c[nthr].in);
		mpf_add(total.all , total.all, c[nthr].all);
	pthread_mutex_unlock (&mutexcount);

	pthread_exit((void*) 0);
}

int main (int argc, char** argv){
	unsigned int n = 0, t;
	void * status;
	long int it;

	mpf_set_default_prec(F_PREC);
	pthread_mutex_init(&mutexcount, NULL);


	for( it = 0; it < N_THREADS; it++){
		init_randcore(rc+it);
		init_counters(c+it);
	}
	init_counters(&total);
	
	t = time(NULL);

	while(N_OUT > n++){
		mpf_set_ui(total.in, 0);
		mpf_set_ui(total.all, 0); 

		for(it = 0; it < N_THREADS; it++)
			pthread_create(&callThd[it], NULL, mc_rand_th, (void *) it);

		for(it = 0; it < N_THREADS; it++)
  			pthread_join(callThd[it], &status);

		calc_pi(&total);
		printf("It %d - %u rands - %d segundos\n", n, n*RANDS_BY_OUT*N_THREADS, (int) time(NULL)-t); 
		save_it(&total, IT_FILENAME);
	}

	for( it = 0; it < N_THREADS; it++){
		clear_randcore(rc+it);
		clear_counters(c+it);
	}
	clear_counters(c+N_THREADS);
	
	return EXIT_SUCCESS;
}
